/*
 * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package com.sun.corba.se.spi.oa;

import org.omg.PortableInterceptor.ObjectReferenceTemplate;
import org.omg.PortableInterceptor.ObjectReferenceFactory;

import org.omg.CORBA.Policy;

import org.omg.PortableInterceptor.ACTIVE;

import com.sun.corba.se.spi.copyobject.ObjectCopierFactory;
import com.sun.corba.se.spi.ior.IORFactories;
import com.sun.corba.se.spi.ior.IORTemplate;
import com.sun.corba.se.spi.ior.ObjectAdapterId;
import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.oa.OADestroyed;
import com.sun.corba.se.spi.oa.ObjectAdapter;
import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.protocol.PIHandler;

import com.sun.corba.se.impl.logging.POASystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.oa.poa.Policies;

abstract public class ObjectAdapterBase extends org.omg.CORBA.LocalObject
    implements ObjectAdapter {

  private ORB orb;

  // Exception wrappers
  private final POASystemException _iorWrapper;
  private final POASystemException _invocationWrapper;
  private final POASystemException _lifecycleWrapper;
  private final OMGSystemException _omgInvocationWrapper;
  private final OMGSystemException _omgLifecycleWrapper;

  // Data related to the construction of object references and
  // supporting the Object Reference Template.
  private IORTemplate iortemp;
  private byte[] adapterId;
  private ObjectReferenceTemplate adapterTemplate;
  private ObjectReferenceFactory currentFactory;

  public ObjectAdapterBase(ORB orb) {
    this.orb = orb;
    _iorWrapper = POASystemException.get(orb,
        CORBALogDomains.OA_IOR);
    _lifecycleWrapper = POASystemException.get(orb,
        CORBALogDomains.OA_LIFECYCLE);
    _omgLifecycleWrapper = OMGSystemException.get(orb,
        CORBALogDomains.OA_LIFECYCLE);
    _invocationWrapper = POASystemException.get(orb,
        CORBALogDomains.OA_INVOCATION);
    _omgInvocationWrapper = OMGSystemException.get(orb,
        CORBALogDomains.OA_INVOCATION);
  }

  public final POASystemException iorWrapper() {
    return _iorWrapper;
  }

  public final POASystemException lifecycleWrapper() {
    return _lifecycleWrapper;
  }

  public final OMGSystemException omgLifecycleWrapper() {
    return _omgLifecycleWrapper;
  }

  public final POASystemException invocationWrapper() {
    return _invocationWrapper;
  }

  public final OMGSystemException omgInvocationWrapper() {
    return _omgInvocationWrapper;
  }

  /*
   * This creates the complete template.
   * When it is done, reference creation can proceed.
   */
  final public void initializeTemplate(ObjectKeyTemplate oktemp,
      boolean notifyORB, Policies policies, String codebase,
      String objectAdapterManagerId, ObjectAdapterId objectAdapterId) {
    adapterId = oktemp.getAdapterId();

    iortemp = IORFactories.makeIORTemplate(oktemp);

    // This calls acceptors which create profiles and may
    // add tagged components to those profiles.
    orb.getCorbaTransportManager().addToIORTemplate(
        iortemp, policies,
        codebase, objectAdapterManagerId, objectAdapterId);

    adapterTemplate = IORFactories.makeObjectReferenceTemplate(orb,
        iortemp);
    currentFactory = adapterTemplate;

    if (notifyORB) {
      PIHandler pih = orb.getPIHandler();
      if (pih != null)
      // This runs the IORInterceptors.
      {
        pih.objectAdapterCreated(this);
      }
    }

    iortemp.makeImmutable();
  }

  final public org.omg.CORBA.Object makeObject(String repId, byte[] oid) {
    return currentFactory.make_object(repId, oid);
  }

  final public byte[] getAdapterId() {
    return adapterId;
  }

  final public ORB getORB() {
    return orb;
  }

  abstract public Policy getEffectivePolicy(int type);

  final public IORTemplate getIORTemplate() {
    return iortemp;
  }

  abstract public int getManagerId();

  abstract public short getState();

  final public ObjectReferenceTemplate getAdapterTemplate() {
    return adapterTemplate;
  }

  final public ObjectReferenceFactory getCurrentFactory() {
    return currentFactory;
  }

  final public void setCurrentFactory(ObjectReferenceFactory factory) {
    currentFactory = factory;
  }

  abstract public org.omg.CORBA.Object getLocalServant(byte[] objectId);

  abstract public void getInvocationServant(OAInvocationInfo info);

  abstract public void returnServant();

  abstract public void enter() throws OADestroyed;

  abstract public void exit();

  abstract protected ObjectCopierFactory getObjectCopierFactory();

  // Note that all current subclasses share the same implementation of this method,
  // but overriding it would make sense for OAs that use a different InvocationInfo.
  public OAInvocationInfo makeInvocationInfo(byte[] objectId) {
    OAInvocationInfo info = new OAInvocationInfo(this, objectId);
    info.setCopierFactory(getObjectCopierFactory());
    return info;
  }

  abstract public String[] getInterfaces(Object servant, byte[] objectId);
}
